前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# koa-router中间件

30 秒速记

  • koa-router 把「方法 + 路径 → 处理函数」做成一张表,支持 /:id 参数、前缀、嵌套和路由级中间件
  • 两个都要挂:router.routes() 负责分发,router.allowedMethods() 负责 405 / 501 和 OPTIONS
  • 包名变迁:老教程是 koa-router(Koa 2 配 7.x),现在维护的是 @koa/router
  • ctx.params 里全是字符串而且是用户填的,转类型、校验、鉴权都要自己做
  • 路由级中间件也走洋葱模型,鉴权放在处理函数前面

koa-router 就是把原生路由里那一堆 if / switch 换成一张「方法 + 路径 → 处理函数」的表,它本身也是一个 Koa 中间件。 用法是 router.get('/user/:id', handler) 注册,最后 app.use(router.routes()).use(router.allowedMethods()) 挂上去。routes() 负责匹配和分发;allowedMethods() 负责路径存在但方法不对时回 405,方法压根不认识时回 501,还会自动应答 OPTIONS。包名要留意,老教程里是 koa-router,现在官方维护的是 @koa/router,用法基本一致,新项目装后者。

理解「koa-router中间件」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 middleware 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

一个带路径参数、前缀和路由级中间件的完整例子:

const Koa = require('koa')
const Router = require('@koa/router')   // 老项目里是 require('koa-router')

const app = new Koa()
const router = new Router({ prefix: '/api' })

// 路由级中间件:只对挂了它的路由生效,先鉴权再进处理函数
const auth = async (ctx, next) => {
  if (!ctx.get('Authorization')) ctx.throw(401, '未登录')
  await next()
}

router.get('/users/:id', auth, ctx => {
  const id = Number(ctx.params.id)      // params 永远是字符串
  if (!Number.isInteger(id)) ctx.throw(400, 'id 不合法')
  ctx.body = { id }
})

app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)

// GET    /api/users/1   带 Authorization -> {"id":1}
// GET    /api/users/1   不带             -> 401 未登录
// GET    /api/users/abc 带 Authorization -> 400 id 不合法
// DELETE /api/users/1                    -> 405,Allow: HEAD, GET
@前端进阶之旅: 代码已经复制到剪贴板

执行顺序和 Koa 的洋葱模型一样:请求先过 app.use 注册的全局中间件,再进 router.routes(),匹配到路由后依次执行 auth、处理函数。allowedMethods() 放在 routes() 后面,只有在没有路由真正处理这个请求时,它才会根据匹配情况补上 405 / 501 或 OPTIONS 的响应。

面试官追问

追问 1只挂了 router.routes(),对一个只注册了 GET 的地址发 DELETE,返回什么?
参考回答

404。挂上 allowedMethods() 之后变成 405 Method Not Allowed,响应头带 Allow: HEAD, GET;如果是 PURGE 这种路由器不认识的方法,回 501 Not Implemented。

追问 2/users/:id 拿到的 ctx.params.id,能直接拿去查库吗?
参考回答

不能。它是字符串,而且是用户随便填的,/users/abc 也能进来。先转类型、校验格式,查库用参数化查询,再确认当前用户有没有权限看这个 id。

追问 3鉴权写在 app.use 里,还是写在路由上?
参考回答

全站都要登录,就 app.use(auth) 放在 router.routes() 前面;只有部分接口要鉴权,就写成路由级中间件 router.get('/admin', auth, handler),或者给这组接口单独建一个 Router 再统一 use(auth)。

追问 4网上有的写 koa-router,有的写 @koa/router,有区别吗?
参考回答

是同一个项目,后来迁到 koajs 组织下改名 @koa/router,旧包不再维护。用法基本一样,新项目装 @koa/router;升大版本时注意路径匹配规则变过,跑一遍路由测试再上线。

追问 5未知路径被某个兜底中间件回了 200,怎么查是谁写的响应?
参考回答

在 router.routes() 后面加个打日志的中间件,打 ctx.path、ctx._matchedRoute 和 ctx.status。命中路由时 _matchedRoute 会是注册的路径模板,比如 /users/:id,是 undefined 就说明路由没命中,是后面的兜底接管的。

# koa-router中间件

如果依靠ctx.request.url去手动处理路由,将会写很多处理代码,这时候就需要对应的路由的中间件对路由进行控制,这里介绍一个比较好用的路由中间件koa-router

# 安装koa-router中间件

30 秒速记

  • Koa 2 配 koa-router@7:npm install --save koa-router@7;Koa 1 的 generator 中间件配 5.x
  • 不写版本会装最新主版本,和教程对不上;锁主版本,并提交 package-lock.json
  • 新项目直接 npm i @koa/router,旧包已不再维护
  • 装完 npm ls koa-router 看实际版本;部署用 npm ci,以 lock 文件为准
  • npm 5+ 起 install 默认写进 dependencies,--save 可以省

Koa 2 用 koa-router 要装 7.x:npm install --save koa-router@7,版本号要写明,因为 5.x 是给 Koa 1 的 generator 中间件用的。 显式锁主版本,是为了团队每个人、包括 CI 装到的都是同一套 API。--save 现在可以省了,npm 5 以后默认就会写进 dependencies。新项目的话我会直接装 @koa/router,这是同一个库迁到 koajs 组织之后的名字,旧包已经不更新了。装完用 npm ls 看一眼实际装到的版本,别只看 package.json。

# koa2 对应的版本是 7.x
npm install --save koa-router@7
@前端进阶之旅: 代码已经复制到剪贴板

理解「安装koa-router中间件」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 middleware 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

面试官追问

追问 1不写版本号直接 npm install koa-router,会有什么问题?
参考回答

会装到当时的最新版,主版本可能和教程不一样,细节对不上;不同时间装的人还可能装到不同版本。写死主版本,再把 package-lock.json 提交上去。

追问 2koa-router@7 和 @koa/router,该选哪个?
参考回答

已经在用 7.x 的老项目没出问题就别折腾;新项目选 @koa/router,还在持续修复问题和安全漏洞。迁移时注意路径语法的变化,比如通配符的写法,先跑一遍路由测试。

追问 3package.json 里写的是 ^7.4.0,怎么知道线上到底装的哪个版本?
参考回答

^7.4.0 允许装 7.x 里任何更高的版本,真正决定装哪个的是 lock 文件。看 npm ls koa-router,部署用 npm ci 严格按 lock 装,别用 npm install。

追问 4Koa 1 的老项目装了 koa-router@7,一启动就报错,为什么?
参考回答

Koa 1 要求中间件是 function*,app.use 会直接拒绝 7.x 返回的普通函数中间件。Koa 1 就用 koa-router@5,或者把项目整体升到 Koa 2。

追问 5安装成功了,能说路由已经接好了吗?
参考回答

不能,装上只是进了 node_modules

基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

koa-router中间件|Nodejs专题系列

# koa-router中间件

30 秒速记

  • koa-router 把「方法 + 路径 → 处理函数」做成一张表,支持 /:id 参数、前缀、嵌套和路由级中间件
  • 两个都要挂:router.routes() 负责分发,router.allowedMethods() 负责 405 / 501 和 OPTIONS
  • 包名变迁:老教程是 koa-router(Koa 2 配 7.x),现在维护的是 @koa/router
  • ctx.params 里全是字符串而且是用户填的,转类型、校验、鉴权都要自己做
  • 路由级中间件也走洋葱模型,鉴权放在处理函数前面

koa-router 就是把原生路由里那一堆 if / switch 换成一张「方法 + 路径 → 处理函数」的表,它本身也是一个 Koa 中间件。 用法是 router.get('/user/:id', handler) 注册,最后 app.use(router.routes()).use(router.allowedMethods()) 挂上去。routes() 负责匹配和分发;allowedMethods() 负责路径存在但方法不对时回 405,方法压根不认识时回 501,还会自动应答 OPTIONS。包名要留意,老教程里是 koa-router,现在官方维护的是 @koa/router,用法基本一致,新项目装后者。

理解「koa-router中间件」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 middleware 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

一个带路径参数、前缀和路由级中间件的完整例子:

const Koa = require('koa')
const Router = require('@koa/router')   // 老项目里是 require('koa-router')

const app = new Koa()
const router = new Router({ prefix: '/api' })

// 路由级中间件:只对挂了它的路由生效,先鉴权再进处理函数
const auth = async (ctx, next) => {
  if (!ctx.get('Authorization')) ctx.throw(401, '未登录')
  await next()
}

router.get('/users/:id', auth, ctx => {
  const id = Number(ctx.params.id)      // params 永远是字符串
  if (!Number.isInteger(id)) ctx.throw(400, 'id 不合法')
  ctx.body = { id }
})

app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)

// GET    /api/users/1   带 Authorization -> {"id":1}
// GET    /api/users/1   不带             -> 401 未登录
// GET    /api/users/abc 带 Authorization -> 400 id 不合法
// DELETE /api/users/1                    -> 405,Allow: HEAD, GET
@前端进阶之旅: 代码已经复制到剪贴板

执行顺序和 Koa 的洋葱模型一样:请求先过 app.use 注册的全局中间件,再进 router.routes(),匹配到路由后依次执行 auth、处理函数。allowedMethods() 放在 routes() 后面,只有在没有路由真正处理这个请求时,它才会根据匹配情况补上 405 / 501 或 OPTIONS 的响应。

面试官追问

追问 1只挂了 router.routes(),对一个只注册了 GET 的地址发 DELETE,返回什么?
参考回答

404。挂上 allowedMethods() 之后变成 405 Method Not Allowed,响应头带 Allow: HEAD, GET;如果是 PURGE 这种路由器不认识的方法,回 501 Not Implemented。

追问 2/users/:id 拿到的 ctx.params.id,能直接拿去查库吗?
参考回答

不能。它是字符串,而且是用户随便填的,/users/abc 也能进来。先转类型、校验格式,查库用参数化查询,再确认当前用户有没有权限看这个 id。

追问 3鉴权写在 app.use 里,还是写在路由上?
参考回答

全站都要登录,就 app.use(auth) 放在 router.routes() 前面;只有部分接口要鉴权,就写成路由级中间件 router.get('/admin', auth, handler),或者给这组接口单独建一个 Router 再统一 use(auth)。

追问 4网上有的写 koa-router,有的写 @koa/router,有区别吗?
参考回答

是同一个项目,后来迁到 koajs 组织下改名 @koa/router,旧包不再维护。用法基本一样,新项目装 @koa/router;升大版本时注意路径匹配规则变过,跑一遍路由测试再上线。

追问 5未知路径被某个兜底中间件回了 200,怎么查是谁写的响应?
参考回答

在 router.routes() 后面加个打日志的中间件,打 ctx.path、ctx._matchedRoute 和 ctx.status。命中路由时 _matchedRoute 会是注册的路径模板,比如 /users/:id,是 undefined 就说明路由没命中,是后面的兜底接管的。

# koa-router中间件

如果依靠ctx.request.url去手动处理路由,将会写很多处理代码,这时候就需要对应的路由的中间件对路由进行控制,这里介绍一个比较好用的路由中间件koa-router

# 安装koa-router中间件

30 秒速记

  • Koa 2 配 koa-router@7:npm install --save koa-router@7;Koa 1 的 generator 中间件配 5.x
  • 不写版本会装最新主版本,和教程对不上;锁主版本,并提交 package-lock.json
  • 新项目直接 npm i @koa/router,旧包已不再维护
  • 装完 npm ls koa-router 看实际版本;部署用 npm ci,以 lock 文件为准
  • npm 5+ 起 install 默认写进 dependencies,--save 可以省

Koa 2 用 koa-router 要装 7.x:npm install --save koa-router@7,版本号要写明,因为 5.x 是给 Koa 1 的 generator 中间件用的。 显式锁主版本,是为了团队每个人、包括 CI 装到的都是同一套 API。--save 现在可以省了,npm 5 以后默认就会写进 dependencies。新项目的话我会直接装 @koa/router,这是同一个库迁到 koajs 组织之后的名字,旧包已经不更新了。装完用 npm ls 看一眼实际装到的版本,别只看 package.json。

# koa2 对应的版本是 7.x
npm install --save koa-router@7
@前端进阶之旅: 代码已经复制到剪贴板

理解「安装koa-router中间件」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 middleware 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

面试官追问

追问 1不写版本号直接 npm install koa-router,会有什么问题?
参考回答

会装到当时的最新版,主版本可能和教程不一样,细节对不上;不同时间装的人还可能装到不同版本。写死主版本,再把 package-lock.json 提交上去。

追问 2koa-router@7 和 @koa/router,该选哪个?
参考回答

已经在用 7.x 的老项目没出问题就别折腾;新项目选 @koa/router,还在持续修复问题和安全漏洞。迁移时注意路径语法的变化,比如通配符的写法,先跑一遍路由测试。

追问 3package.json 里写的是 ^7.4.0,怎么知道线上到底装的哪个版本?
参考回答

^7.4.0 允许装 7.x 里任何更高的版本,真正决定装哪个的是 lock 文件。看 npm ls koa-router,部署用 npm ci 严格按 lock 装,别用 npm install。

追问 4Koa 1 的老项目装了 koa-router@7,一启动就报错,为什么?
参考回答

Koa 1 要求中间件是 function*,app.use 会直接拒绝 7.x 返回的普通函数中间件。Koa 1 就用 koa-router@5,或者把项目整体升到 Koa 2。

追问 5安装成功了,能说路由已经接好了吗?
参考回答

不能,装上只是进了 node_modules。至少要请求一个注册过的路径、一个没注册的路径、一个方法不对的请求,看到 200、404、405 各就各位才算接好。

# 快速使用koa-router

30 秒速记

  • 子路由只写局部路径,总路由用 router.use('/page', page.routes(), page.allowedMethods()) 挂到前缀下
  • 最终地址 = 前缀 + 局部路径:/page/helloworld、/page/404
  • 应用层最后 app.use(router.routes()).use(router.allowedMethods())
  • allowedMethods():路径对方法不对 → 405 带 Allow;不认识的方法 → 501
  • 按业务拆文件:子模块导出 Router 实例,入口统一装配;也可以 new Router({ prefix: '/page' })

这个例子演示的是路由分组:每个子路由只写自己的局部路径,再由总路由按前缀统一挂载。 home 挂在 / 下,page 挂在 /page 下,所以 page.get('/helloworld') 对外就是 /page/helloworld。这样按业务拆文件很自然,user.js、order.js 各导出一个 Router,入口只管装配。最后一行的 allowedMethods() 别漏,没有它,对 /page/helloworld 发 DELETE 只会得到 404;有了它就是 405 加 Allow: HEAD, GET,前端一看就知道是方法用错了。

← 2.1 原生koa2实现路由3.1 GET请求数据获取 →

fe